Crate if_chain

Source
Expand description

This crate provides a single macro called if_chain!.

if_chain! lets you write long chains of nested if and if let statements without the associated rightward drift. It also supports multiple patterns (e.g. if let Foo(a) | Bar(a) = b) in places where Rust would normally not allow them.

See the associated blog post for the background behind this crate.

§Note about recursion limits

If you run into “recursion limit reached” errors while using this macro, try adding

#![recursion_limit = "1000"]

to the top of your crate.

§Examples

§Quick start

if_chain! {
    if let Some(y) = x;
    if y.len() == 2;
    if let Some(z) = y;
    then {
        do_stuff_with(z);
    }
}

becomes

if let Some(y) = x {
    if y.len() == 2 {
        if let Some(z) = y {
            do_stuff_with(z);
        }
    }
}

§Fallback values with else

if_chain! {
    if let Some(y) = x;
    if let Some(z) = y;
    then {
        do_stuff_with(z)
    } else {
        do_something_else()
    }
}

becomes

if let Some(y) = x {
    if let Some(z) = y {
        do_stuff_with(z)
    } else {
        do_something_else()
    }
} else {
    do_something_else()
}

§Intermediate variables with let

if_chain! {
    if let Some(y) = x;
    let z = y.some().complicated().expression();
    if z == 42;
    then {
       do_stuff_with(y);
    }
}

becomes

if let Some(y) = x {
    let z = y.some().complicated().expression();
    if z == 42 {
        do_stuff_with(y);
    }
}

§Type ascription

let mut x = some_generic_computation();
if_chain! {
    if x > 7;
    let y: u32 = another_generic_computation();
    then { x += y }
    else { x += 1 }
}

becomes

let mut x = some_generic_computation();
if x > 7 {
    let y: u32 = another_generic_computation();
    x += y
} else {
    x += 1
}

§Multiple patterns

if_chain! {
    if let Foo(y) | Bar(y) | Baz(y) = x;
    let Bubbles(z) | Buttercup(z) | Blossom(z) = y;
    then { do_stuff_with(z) }
}

becomes

match x {
    Foo(y) | Bar(y) | Baz(y) => match y {
        Bubbles(z) | Buttercup(z) | Blossom(z) => do_stuff_with(z)
    },
    _ => {}
}

Note that if you use a plain let, then if_chain! assumes that the pattern is irrefutable (always matches) and doesn’t add a fallback branch.

Macros§

  • Macro for writing nested if let expressions.